#ifndef NOSAL_EXEC_INTERNAL_EXEC_MANIFEST_PARSING_ERROR_DOMAIN_H
#define NOSAL_EXEC_INTERNAL_EXEC_MANIFEST_PARSING_ERROR_DOMAIN_H

#include "nosal/core/error_code.h"
#include "nosal/core/exception.h"

namespace netaos {
namespace nosal {
namespace exec {
namespace internal {

enum class ExecManifestParsingErrc : netaos::nosal::core::ErrorDomain::CodeType
{
    kDirectoryStructureCorrupt = 1,  ///< No valid Executables were found in the specified directory.
    kFunctionGroupNotInStateOff = 2,  ///< FunctionGroup to be updated is not in State Off.
    kExecutableNotFound = 3,  ///< Executable not found.
    kNotInitialized = 4,  ///< ExecutablesHandler is not properly configured.
};

class ExecManifestParsingException : public netaos::nosal::core::Exception
{
public:
    explicit ExecManifestParsingException(netaos::nosal::core::ErrorCode&& err)
        : netaos::nosal::core::Exception(std::move(err))
    { }
};

class ExecManifestParsingErrorDomain final : public netaos::nosal::core::ErrorDomain
{

    constexpr static netaos::nosal::core::ErrorDomain::IdType kId
        = 0xc000000000000205ull;  ///< Error domain ID for ExecManifestParsingErrorDomain.

public:
    constexpr ExecManifestParsingErrorDomain() noexcept
        : netaos::nosal::core::ErrorDomain(kId)
    { }

    const char* Name() const noexcept override
    {
        return "ExecManifestParsing";
    }

    const char* Message(netaos::nosal::core::ErrorDomain::CodeType errorCode) const noexcept override
    {
        const ExecManifestParsingErrc code = static_cast<ExecManifestParsingErrc>(errorCode);
        switch (code) {
        case ExecManifestParsingErrc::kDirectoryStructureCorrupt:
            return "Directory structure invalid, no Executables found.";

        case ExecManifestParsingErrc::kFunctionGroupNotInStateOff:
            return "FunctionGroup that shall be updated is not in State Off.";

        case ExecManifestParsingErrc::kExecutableNotFound:
            return "The searched Executable was not found.";

        case ExecManifestParsingErrc::kNotInitialized:
            return "The ExecutablesHandler instance was not properly initialized.";

        default:
            return "An unspecified error occured during Execution Manifest Parsing and Processing.";
        }
    }

    void ThrowAsException(netaos::nosal::core::ErrorCode const& errorCode) const noexcept(false) override
    {
        netaos::nosal::core::ifc::ThrowOrTerminate<ExecManifestParsingException>(errorCode);
    }
};

namespace detail
{
constexpr ExecManifestParsingErrorDomain
    g_execManifestParsingErrorDomain;  ///< Static instance of ExecManifestParsingErrorDomain for MakeErrorCode
}

inline constexpr netaos::nosal::core::ErrorDomain const& GetExecManifestParsingErrorDomain() noexcept
{
    return detail::g_execManifestParsingErrorDomain;
}

inline constexpr netaos::nosal::core::ErrorCode MakeErrorCode(ExecManifestParsingErrc code,
    netaos::nosal::core::ErrorDomain::SupportDataType data) noexcept
{
    return netaos::nosal::core::ErrorCode(
        static_cast<netaos::nosal::core::ErrorDomain::CodeType>(code), GetExecManifestParsingErrorDomain(), data);
}

}  // namespace internal
}  // namespace exec
}  // namespace nosal
}  // namespace netaos

#endif
